﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IceDog.DNF.Library.Common.Captcha
{
    /// <summary>
    /// 获取验证码
    /// </summary>
    public class SimpleCaptcha
    {
        private static readonly string _charStr = "2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,T,U,X,Y,Z";//去除容易出错的字符
        private readonly Random _ran;
        private Bitmap _img;
        private readonly int _count;
        private readonly int _width;
        private readonly int _height;
        /// <summary>
        /// 验证码文字
        /// </summary>
        public string Code { get; set; }
        /// <summary>
        /// 验证码图片
        /// </summary>
        public Bitmap CodeImage { get; set; }
        /// <summary>
        /// 刷新验证码的方法
        /// </summary>
        public void Refresh()
        {
            Code = GetRandomCode(_count);
            CodeImage = GetImage(Code, _width, _height);
        }
        private SimpleCaptcha()
        {
            _ran = new Random();
        }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="count">显示字符数量</param>
        /// <param name="width">图片宽度，单位px</param>
        /// <param name="height">图片高度，单位px</param>
        public SimpleCaptcha(int count, int width, int height)
            : this()
        {
            _count = count;
            _width = width;
            _height = height;
            Refresh();
        }
        ~SimpleCaptcha()
        {
            CodeImage.Dispose();
        }
        //获取验证码
        private string GetRandomCode(int count)
        {
            string[] charArr = _charStr.Split(',');
            var len = charArr.Length;
            int tempIndex = -1;
            var result = string.Empty;
            for (int i = 0; i < count; i++)
            {
                var newIndex = _ran.Next(len);
                if (newIndex == tempIndex)//如果连续是相同的字符，重新来一次
                {
                    newIndex = _ran.Next(len);
                }
                tempIndex = newIndex;
                result += charArr[newIndex];
            }
            return result;
        }

        private Bitmap GetImage(string content, int width, int height)
        {
            _img = new Bitmap(width, height);
            Graphics g = Graphics.FromImage(_img);//获取img 对象的gdi+对象
            g.Clear(GetRandomBgColor());//设置背景色
            //绘制背景噪音线
            var pointList = GetRandomHeightList();
            g.DrawBezier(new Pen(GetRandomLineColor(), 2), new Point(-4, pointList[0]), new Point(width * (1 / 5) + _ran.Next(10, 20), pointList[1]), new Point(width * (3 / 5) + _ran.Next(10, 20), pointList[2]), new Point(width + 4, pointList[3]));
            for (int i = 0; i < 2; i++)
            {
                var heightList = GetRandomHeightList();
                var widthList = GetRandomWidthList();
                g.DrawBezier(new Pen(GetRandomLineColor(), 1), new Point(widthList[0], heightList[0]), new Point(widthList[1], heightList[1]), new Point(widthList[2], heightList[2]), new Point(widthList[3], heightList[3]));
            }
            //绘制内容
            var contentArr = content.ToCharArray();
            for (var i = 0; i < contentArr.Length; i++)
            {
                Brush brush = new SolidBrush(GetRandomFontColor());
                Font font = new Font(new FontFamily("Microsoft Sans Serif"), _ran.Next(14, 16), FontStyle.Bold);
                g.DrawString(contentArr[i].ToString(), font, brush, _ran.Next(0, 3) + i * font.Size, _ran.Next(2, height / 5));
            }
            //绘制前景噪音点
            for (int i = 0; i < 25; i++)
            {
                var p = GetRandomPoint(width, height);
                _img.SetPixel(p.X, p.Y, GetRandomLineColor());
            }
            return _img;
        }
        private Point GetRandomPoint(int maxX, int maxY)
        {
            return new Point()
            {
                X = _ran.Next(maxX),
                Y = _ran.Next(maxY)
            };
        }
        /// <summary>
        /// 获取随机合适的高度值用来绘制
        /// </summary>
        /// <returns></returns>
        private int[] GetRandomHeightList()
        {
            var arr = new int[4];
            var flag = _ran.Next(2) > 0;
            for (var i = 0; i < 4; i++)
            {
                var num = 0;
                if (flag)
                {
                    num = _height - _ran.Next(_height * 2 / 3, _height - 5);
                    flag = false;
                }
                else
                {
                    num = _height - _ran.Next(2, _height / 3);
                    flag = true;
                }
                arr[i] = num;
            }
            return arr;
        }

        private int[] GetRandomWidthList()
        {
            var arr = new int[4];
            for (int i = 0; i < 4; i++)
            {
                arr[i] = _ran.Next(0, _width);
            }
            return arr;
        }

        private Color GetRandomBgColor()
        {
            Color[] list = { Color.White, Color.Cornsilk };
            return list[_ran.Next(0, list.Length)];
        }
        private Color GetRandomLineColor()
        {
            Color[] list = { Color.Black, Color.Blue, Color.Brown, Color.DarkBlue, Color.Firebrick, Color.Indigo, Color.ForestGreen, Color.Navy, };
            return list[_ran.Next(0, list.Length)];
        }

        private Color GetRandomFontColor()
        {
            Color[] list =
            {
                Color.LightSeaGreen, Color.LightCoral,Color.Black, Color.CadetBlue,
                Color.LightSlateGray, Color.LimeGreen,
            };
            return list[_ran.Next(0, list.Length)];
        }
    }
}
